/**
 * Copyright [2019] [LiBo/Alex of copyright liboware@gmail.com ]
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hyts.datasource.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.hyts.datasource.aspect.MultiDataSourceAspect;
import com.hyts.datasource.context.DataSourceContextHolder;
import com.hyts.datasource.context.MultiDataSourceRoute;
import com.hyts.datasource.enums.DatasourceAttribute;
import com.hyts.datasource.enums.SupportDatasource;
import com.hyts.datasource.properties.MultiDataSourceProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Primary;
import org.springframework.util.Assert;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

/**
 * @project-name:coffice-toolbox
 * @package-name:com.hyts.datasource.config
 * @author:LiBo/Alex
 * @create-date:2020-05-09 10:05
 * @copyright:libo-alex4java
 * @email:liboware@gmail.com
 * @description:
 */
@EnableConfigurationProperties(MultiDataSourceProperties.class)
@Configuration
public class MultiDataSourceConfiguration {

    @Bean
    public MultiDataSourceAspect multiDataSourceAspect(){
        return new MultiDataSourceAspect();
    }


    @ConfigurationProperties(prefix = "spring.multi")
    @Bean
    public MultiDataSourceProperties multiDataSourceProperties(){
        return new MultiDataSourceProperties();
    }

    @Bean
    @Primary
    @ConditionalOnMissingBean
    @DependsOn("multiDataSourceProperties")
    public DataSource dataSource(MultiDataSourceProperties multiDataSourceProperties) {
        System.out.println("init datasource");
        MultiDataSourceRoute dynamicDataSource = new MultiDataSourceRoute();
        //设置原始数据源
        HashMap<Object, Object> dataSourcesMap = new HashMap<>();
        HashSet<SupportDatasource> dataSet = DataSourceContextHolder.getDataSourceSet();
        for (SupportDatasource supportDatasourceEnum : dataSet) {
            DataSource dataSource = this.createDataSourceProperties(supportDatasourceEnum,multiDataSourceProperties);
            dataSourcesMap.put(supportDatasourceEnum.toString(), dataSource);
        }
        dynamicDataSource.setTargetDataSources(dataSourcesMap);
        dynamicDataSource.setDefaultTargetDataSource(createDataSourceProperties(SupportDatasource.MASTER,multiDataSourceProperties));
        return dynamicDataSource;
    }

    /**
     * 创建数据源配置
     * @param supportDatasourceEnum
     * @return
     */
    private synchronized DataSource createDataSourceProperties(SupportDatasource supportDatasourceEnum,MultiDataSourceProperties multiDataSourceProperties) {
        Assert.notEmpty(multiDataSourceProperties.getDatasource(),"初始化的数据源不允许为空配置");
        Map<String,String> datasourceMap = multiDataSourceProperties.getDatasource().get(supportDatasourceEnum.toString());
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUrl(datasourceMap.get(DatasourceAttribute.URL.getAttribute()));
        druidDataSource.setUsername(DatasourceAttribute.USER_NAME.getAttribute());
        druidDataSource.setPassword(DatasourceAttribute.PASSWORD.getAttribute());
        //具体配置
        druidDataSource.setMaxActive(100);
        druidDataSource.setInitialSize(5);
        druidDataSource.setMinIdle(1);
        druidDataSource.setMaxWait(30000);
        //间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
        druidDataSource.setTimeBetweenConnectErrorMillis(60000);
        return druidDataSource;
    }



}
